package com.inepex.inechart.client.cartesian;

import com.inepex.inechart.client.jobscheduler.HasScheduledJob;
import com.inepex.inechart.shared.CartesianException;
import com.inepex.inegraphics.impl.client.DrawingAreaGWT;
import com.inepex.inegraphics.shared.gobjects.GraphicalObject;

public class CartesianJobScheduler implements HasScheduledJob {
	
	public static final int defaultUpdatePartTreshold = 24;
	
	public enum CartesianJob{
		/**
		 * clear model and graphical objects
		 */
		clear,
		/**
		 * things needed to do before axis padding calculation
		 */
		preparation_for_axes,
		/**
		 * paddings should be calculated for a module's axes if it is auto aligned
		 */
		padding_calculation_for_axes,
		/**
		 * set the new sizes for display engine and cartesian assist
		 */
		set_cartesian_assist,
		/**
		 * {@link GraphicalObject} creation for axes
		 */
		GO_creation_for_axes,
		/**
		 * model preparation / calculation
		 */
		preparation_for_model,
		/**
		 * {@link GraphicalObject} creation for model
		 */
		GO_creation_for_model,
		/**
		 * flush {@link GraphicalObject}s to {@link DrawingAreaGWT} and update it afterwards
		 */
		draw,
		/**
		 * update display engine
		 */
		update_display
		
	}

	public static final CartesianJob[] resolutionChangeUpdateJobSequence = new CartesianJob[]{
		CartesianJob.clear,
		CartesianJob.preparation_for_axes,
		CartesianJob.padding_calculation_for_axes,
		CartesianJob.set_cartesian_assist,
		
		CartesianJob.GO_creation_for_axes,
		CartesianJob.preparation_for_model,
		CartesianJob.GO_creation_for_model,
		CartesianJob.draw,
		CartesianJob.update_display
	};
	
	public static final CartesianJob[] clearOnly = new CartesianJob[]{
		CartesianJob.clear
	};

	protected CartesianChartModuleGWT cartesianChartModuleGWT;
	protected CartesianJob[] actualJobSequence;
	protected int actualJobIndex;

	public CartesianJobScheduler(CartesianChartModuleGWT CartesianChartModuleGWT) {
		super();
		this.cartesianChartModuleGWT = CartesianChartModuleGWT;
	}

	public void startJobSequence(CartesianJob[] jobSequence) throws CartesianException{
		actualJobSequence = jobSequence;
		actualJobIndex = -1;
		nextJobOrFinish();
	}
	
	public boolean isResolutionChangeUpdateInProgress(){
		return actualJobSequence == resolutionChangeUpdateJobSequence;
	}

	protected void nextJobOrFinish() throws CartesianException{
		if(++actualJobIndex >= actualJobSequence.length){
			cartesianChartModuleGWT.onJobSequenceFinish();
		}
		else{
			switch(actualJobSequence[actualJobIndex]){
			case preparation_for_axes:
				cartesianChartModuleGWT.prepareAxes(this);
				break;
			case padding_calculation_for_axes:
				cartesianChartModuleGWT.calcPaddingForAxes(this);
				break;
			case GO_creation_for_axes:
				cartesianChartModuleGWT.createGOsForAxes(this);
				break;
			case preparation_for_model:
				cartesianChartModuleGWT.prepareModel(this);
				break;
			case GO_creation_for_model:
				cartesianChartModuleGWT.createModelGOs(this);
				break;
			case clear:
				cartesianChartModuleGWT.clear(this);
				break;
			case set_cartesian_assist:
				cartesianChartModuleGWT.setDimensionsCreateWidgets(this);
				break;
			case draw:
				cartesianChartModuleGWT.draw(this);
				break;
			case update_display:
				cartesianChartModuleGWT.updateDisplayEngine(this);
				break;
			}
		}
	}

	@Override
	public void onJobFinish() {
		try {
			nextJobOrFinish();
		} catch (CartesianException e) {
			e.printStackTrace();
		}
	}

}
